home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
p063b9s.zip
/
UNIT
/
POPED.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-04-20
|
36KB
|
1,137 lines
UNIT PopEd;
{╔══════════════════════════════════════════════════════════════════════════╗}
{║ Portal Msg-Editor Last changed: 20.04.96 SA ║}
{║ ║}
{║ (C) Copyright 1989-94 by ║}
{║ Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager ║}
{║ ║}
{║ This source may not be given to anybody, without the written permission ║}
{║ from The Portal Team. ║}
{╚══════════════════════════════════════════════════════════════════════════╝}
{$I POPDEFS.Inc}
INTERFACE
USES Use32;
PROCEDURE PopEdMain;
IMPLEMENTATION
USES
Dos,
PoPTypes, NetFile, Globals, RBrowser, OproUtil, Util, StrUtil, Resource,
LogFile, FileUtil, Nodelist,
OpString, OpEntry, OpBrowse, OpCmd, OpCrt, OpWindow, OpEditor, OpInline,
Oproot, OpSelect,
MKFile, MKMsgAbs, MkObject, MKGlobT;
TYPE
PPOPEDArea = ^TPOPEDArea;
TPOPEDArea = RECORD
Directory : PathStr; { QBBS/SBBS/RA=Board number, other=Directory path }
EchoNames : ARRAY[1..3] Of S32;{ Echo mail tags }
Origin : S50; { Origin line, if any }
Pvt2EMail : Boolean;
Description: S40; { The title or description of this area }
AreaType : Byte; { 0=Hudson, 1=Msg 2=Squish 3=EzyCom 4=JAM}
UsedAka : Byte; { Which AKA address to use, 0=Main address }
NumMsg : Word;
LastRead : Word;
END;
PPOPEDInfo = ^TPOPEDInfo;
TPOPEDInfo = RECORD
address : S20;
description : S40;
echotag : S32;
originaladdress : S20;
originaldate : S10;
originalsubject : S72;
originalsysopfirstname : S35;
originalsysoplastname : S35;
originalsysopname : S35;
originaltime : S5;
originaltoaddress : S20;
originaltosysopfirstname : S35;
originaltosysoplastname : S35;
originaltosysopname : S35;
QuoteInitials : S4;
subject : S72;
sysopfirstname : S35;
sysoplastname : S35;
sysopname : S35;
toaddress : S20;
tosysopfirstname : S35;
tosysoplastname : S35;
tosysopname : S35;
EditorStartLine : Integer;
END;
MyBrowserPtr = ^MyBrowser;
MyBrowser = Object(Browser)
procedure brDrawLine(Y : Byte); virtual; {!!.03}
END;
MyEditorPtr = ^MyEditor;
MyEditor = Object(TextEditor)
procedure meDrawLine(St : String; LineNum : Integer); Virtual;
END;
Const
StLen = 81;
TmpName = '$POPED$.MSG';
TmpName2 = '$POPED$.ARE';
TmpName3 = '$POPED$.TMP';
Var
Save : Boolean;
f : File;
ff : File;
Msg : AbsMsgPtr;
MsgNumber : LongInt;
BrowseWin : MyBrowserPtr;
EditorWin : MyEditorPtr;
Status : Integer;
Finished : Boolean;
HeaderWin : WindowPtr;
POPEDArea : PPOPEDArea;
POPEDInfo : PPOPEDInfo;
EditorLineNumber : Integer;
procedure InsertHex(var Dest; Ch : Char);
{-Convert Ch to hex and store in Dest}
inline(
$58/ {pop ax ;char into al}
$5F/ {pop di ;es:di => dest}
$07/ {pop es}
$88/$C4/ {mov ah,al ;ah = al}
$80/$E4/$0F/ {and ah,$0f ;ah has low nibble}
$80/$FC/$0A/ {cmp ah,$0a ;ah >= $a?}
$72/$05/ {jb x1}
$80/$C4/$37/ {add ah,'A'-$a}
$EB/$03/ {jmp short x2}
{x1:}
$80/$C4/$30/ {add ah,'0'}
{x2:}
$B1/$04/ {mov cl,4 ;al has high nibble}
$D2/$E8/ {shr al,cl}
$3C/$0A/ {cmp al,$0a ;al >= $a?}
$72/$04/ {jb x3}
$04/$37/ {add al,'A'-$a}
$EB/$02/ {jmp short x4}
{x3:}
$04/$30/ {add al,'0'}
{x4:}
$AB); {stosw ;store it}
procedure MyBrowser.brDrawLine(Y : Byte);
{-Draw working line to row Y of screen}
label
EndLoop, EndHexLoop, NormalChar;
var
X : Integer;
XTab : Integer;
XRight : Integer;
MNum : Word;
Attr : Byte;
SLine : String;
SRec : record {Record used to shift string right by one}
SLen : Byte;
ShStr : String;
end absolute SLine;
HexSt : string[8];
Col1, Col2 : Word;
Count : Word;
ColOfs : Word;
LastPos : LongInt;
WinWidth : Word;
{$IFDEF UseMouse}
SaveMouse : Boolean;
{$ENDIF}
begin
{Check for markers}
MNum := $FFFF;
for X := 0 to MaxMarker do
if brMarkers[X].FilePos = WorkPos then
MNum := X;
{Select attribute for line}
if WorkPos = brFndPos then
Attr := ColorMono(brHighlightColor, brHighlightMono)
else if brBlockOn and (WorkPos >= brBlkBegin.FilePos) and (WorkPos < brBlkEnd.FilePos) then
Attr := ColorMono(brBlockColor, brBlockMono)
else
Attr := ColorMono(wTextColor, wTextMono);
{are we in hex mode?}
ColOfs := brColOfs;
LastPos := brLastPos;
WinWidth := brWinWidth;
if FlagIsSet(brOptions, brHexMode) then begin
{Initialize screen line} {!!.03}
if brHex8 then {!!.03}
SRec.SLen := Hex8Width {!!.03}
else {!!.03}
SRec.SLen := Hex16Width; {!!.03}
{skip all this if we're past end-of-file}
if (WorkPos > LastPos) or (brColOfs >= SRec.SLen) then begin {!!.03}
SRec.SLen := 0;
goto EndHexLoop;
end;
FillChar(SLine[1], SRec.SLen, ' ');
{plug in file offset and initialize}
HexSt := HexL(WorkPos);
if SRec.SLen = Hex8Width then begin
Col1 := 8;
Col2 := Hex8Width-7;
Count := 8;
MoveFast(HexSt[4], SLine[1], 5); {!!.01}
end
else begin
Col1 := 10;
Col2 := Hex16Width-15;
Count := 16;
MoveFast(HexSt[3], SLine[1], 6); {!!.01}
end;
for X := 1 to Count do
{do nothing if beyond end of file}
if WorkPos <= LastPos then begin
{get next character}
if (WorkOfs >= WorkEnd) then
brGetWorkingChar
else
Byte(WorkChr) := Byte(WorkPtr^) and brMask;
{plug everything in}
InsertHex(SLine[Col1], WorkPtr^);
if brMask = $FF then
SLine[Col2] := WorkChr
else case WorkChr of
' '..'~' :
SLine[Col2] := WorkChr
else
SLine[Col2] := '.';
end;
{advance counters}
Inc(Col1, 3);
Inc(Col2, 1);
Inc(WorkPos);
Inc(WorkOfs);
end;
{if we're scrolled, shift text to the left}
if (ColOfs >= WinWidth) then
SRec.SLen := 0
else if (ColOfs > 0) then begin
MoveFast(SLine[ColOfs+1], SLine[1], SRec.SLen-ColOfs); {!!.01}
Dec(SRec.SLen, ColOfs);
end;
EndHexLoop:
{pad end of line with blanks}
if WinWidth > SRec.SLen then
FillChar(SLine[SRec.SLen+1], WinWidth-SRec.SLen, ' ');
SRec.SLen := WinWidth;
end
else begin
{Initialize screen line}
SRec.SLen := WinWidth;
FillChar(SLine[1], WinWidth, ' ');
{skip all this if we're past end-of-file}
if WorkPos > LastPos then
goto EndLoop;
X := 1;
XRight := ColOfs+WinWidth;
while X <= XRight do begin
if WorkPos > LastPos then begin
{Past end of file}
if X > ColOfs then
{Transfer character to line buffer}
SLine[X-ColOfs] := ' ';
Inc(X);
end
else begin
if (WorkOfs >= WorkEnd) then
brGetWorkingChar
else
Byte(WorkChr) := Byte(WorkPtr^) and brMask;
case WorkChr of
^M : {End of line}
goto EndLoop;
^I : {Expand tabs}
if FlagIsSet(brOptions, brTabExpand) then begin
XTab := ((X+7) and $FFF8)+1; {!!.13}
if XTab > XRight then
XTab := XRight;
while X < XTab do begin
if X > ColOfs then
SLine[X-ColOfs] := ' ';
Inc(X);
end;
Inc(WorkPos);
Inc(WorkOfs);
end
else
goto NormalChar;
else begin
NormalChar:
if X > ColOfs then begin
if (WorkChr = ^Z) then
WorkChr := ' ';
{Transfer character to line buffer}
SLine[X-ColOfs] := WorkChr;
end;
Inc(X);
Inc(WorkPos);
Inc(WorkOfs);
end;
end;
end;
end;
end;
EndLoop:
{$IFDEF UseMouse}
HideMousePrim(SaveMouse);
{$ENDIF}
{Write line buffer to screen}
If Pos('>',Copy(Sline,1,10))<> 0 then
Attr := ColorMono(brHighlightColor, brHighlightMono);
If (Sline[1]=#1) or (Copy(Sline,1,8)='SEEN-BY:') then
Attr := ColorMono(brBlockColor, brBlockMono);
if MNum <> $FFFF then begin
{Put mark at left edge}
FastWrite(Char(Ord('0')+MNum), Y, wXL, ColorMono(brMarkerColor, brMarkerMono));
SRec.ShStr[0] := Char(WinWidth-1);
FastWrite(SRec.ShStr, Y, wXL+1, Attr);
end
else
FastWrite(SLine, Y, wXL, Attr);
{$IFDEF UseMouse}
ShowMousePrim(SaveMouse);
{$ENDIF}
end;
procedure MyEditor.meDrawLine(St : String; LineNum : Integer);
{-Draw the specified line}
var
StLen : Byte absolute St;
SearchLen : Byte absolute teSearchSt;
ASt : string;
AStLen : Byte absolute ASt;
TA, CA, BA, MA, HA : Byte;
I, J : Word;
BLine, ELine : Integer;
BCol, ECol : Byte;
begin
{pad character string}
J := MaxWord(Word(meWinWidth)+meColDelta, 255);
FillChar(St[Succ(StLen)], J-StLen, ' ');
{initialize attribute string}
TA := ColorMono(wTextColor, wTextMono);
FillChar(ASt[1], J, TA);
AStLen := J;
{map control characters}
if (StLen > 0) and LongFlagIsSet(meOptions, teMapCtrls) then begin
CA := ColorMono(meCtrlColor, meCtrlMono);
for I := meColDelta+1 to StLen do
if St[I] < ' ' then begin
Inc(Byte(St[I]), 64);
ASt[I] := Char(CA);
end;
end;
{account for block markers}
if LongFlagIsSet(meOptions, teBlockOn) then begin
BLine := teBlkBegin.Line;
ELine := teBlkEnd.Line;
if teBlkBegin.Col > J then
BCol := J
else
BCol := teBlkBegin.Col;
if teBlkEnd.Col > J then
ECol := J
else
ECol := teBlkEnd.Col;
BA := ColorMono(teBlockColor, teBlockMono);
if (LineNum >= BLine) and (LineNum <= ELine) then
{is this the first line of the block?}
if (LineNum = BLine) then
{is this also the last line of the block?}
if (LineNum = ELine) then
{entire block is within this one line}
FillChar(ASt[BCol], ECol-BCol, BA)
else
{first line of block}
FillChar(ASt[BCol], Succ(J-BCol), BA)
{is this the last line of the block?}
else if (LineNum = ELine) then
{first part of line is inside the block}
FillChar(ASt[1], ECol-1, BA)
else
{line is completely within the block}
FillChar(ASt[1], J, BA);
end;
{account for text markers}
if LongFlagIsSet(meOptions, teMarkersOn) and (teMarkerFlags <> 0) then begin
MA := ColorMono(teMarkerColor, teMarkerMono);
for I := 0 to MaxMarker do
with teMarkers[I] do
if LineNum = Line then begin
St[Col] := Char(Ord('0')+I);
ASt[Col] := Char(MA);
end;
end;
{highlight string at cursor?}
if (LineNum = meCurLine) and LongFlagIsSet(meOptions, teHighlightOn) then begin
HA := ColorMono(teHighlightColor, teHighlightMono);
I := meCurCol;
if not LongFlagIsSet(meOptions, teHighlightBack) then
Dec(I, Pred(SearchLen));
FillChar(ASt[I], SearchLen, HA);
end;
{adjust for ColDelta}
I := meColDelta+1;
if (I > 1) then begin
MoveFast(St[I], St[1], meWinWidth); {!!.01}
MoveFast(ASt[I], ASt[1], meWinWidth); {!!.01}
end;
{set the length bytes}
StLen := meWinWidth;
AStLen := StLen;
If Pos('>',Copy(St,1,10))<> 0 then
FillChar(ASt,AStLen, ColorMono(teHighlightColor, teHighlightMono));
If (St[1]=#1) or (Copy(St,1,8)='SEEN-BY:') then
FillChar(ASt,AStLen, ColorMono(teBlockColor, teBlockMono));
{draw the string}
FastWriteAttr(St, Word(wYL)+(LineNum-meLineAtTop), wXL, ASt)
end;
(*****************************************************************************)
Procedure ProcessInfoRec;
VAR
s : String;
BEGIN
PopEdInfo^.QuoteInitials:='';
s := POPEDInfo^.SysopName;
PopEdInfo^.SysOpFirstName := NextWord(' ',s);
PopEdInfo^.SysOpLastName := '';
While s <> '' do
PopEdInfo^.SysOpLastName := NextWord(' ',s);
s := POPEDInfo^.ToSysopName;
PopEdInfo^.ToSysOpFirstName := NextWord(' ',s);
PopEdInfo^.ToSysOpLastName := '';
While s <> '' do
BEGIN
PopEdInfo^.ToSysOpLastName := NextWord(' ',s);
END;
s:=PopEdInfo^.OriginalSysOpName;
PopEdInfo^.QuoteInitials:=copy(NextWord(' ',s),1,1);
While s <> '' do
PopEdInfo^.QuoteInitials:=PopEdInfo^.QuoteInitials+copy(NextWord(' ',s),1,1);
END;
Procedure ProcessTemplate(MsgMode:Byte);
Var
t,
tt : PbufTextFile;
s : String;
Procedure DoQuotes;
Var
tOld : Text;
STmp,
STmpOut,
StmpRest : String;
QuotePos : Byte;
BEGIN
ProcessInfoRec;
Assign(tOld,Startpath+TmpName);
Reset(TOld);
STmpRest:='';
While not EOF(tOld) do
BEGIN
ReadLn(tOld,STmp);
If Trim(STmpRest)<>'' then STmpRest:=Trim(STmpRest)+' ' ELSE STmpRest:='';
QuotePos:= Pos('>',Copy(Stmp,1,10)); {Skal laves om, så den giver sidste pos!!!}
If QuotePos<> 0 then
BEGIN
Insert('>',STmp,QuotePos);
If STmpRest <> '' then
BEGIN
Insert(STmpRest,STmp,QuotePos+2);
END;
WordWrap(' ' + Trim(STmp) , STmpOut,STmpRest,78,False);
END ELSE
BEGIN
If Trim(STmp + STmpRest)<>'' then
WordWrap(' ' + Trim(PopEdInfo^.QuoteInitials + '> ' + STmpRest + STmp) , STmpOut,STmpRest,78,False)
ELSE
StmpOut:='';
END;
tt^.WriteLn(sTmpOut);
Inc(EditorLineNumber);
END;
Close(tOld);
END;
Function CheckForKeyWord(var sss:String; skey:String; md1,md2:byte):Boolean;
Var
sssTmp : String;
BEGIN
CheckForKeyWord:=True;
If copy(sss,1,length(skey)) = skey then
BEGIN
Delete(sss,1,length(skey));
If md1<>md2 then
BEGIN
CheckForKeyWord:=False;
END;
END;
END;
Function UseThisLine(Var ss:String; md:Byte):Boolean;
Var
UseThis : Boolean;
BEGIN
If copy(ss,1,1) = ';' then
BEGIN
UseThisLine := false;
exit;
END;
If copy(ss,1,1) = '$' then
BEGIN
If not CheckForKeyWord(ss,'$position',0,1) then
BEGIN
UseThisLine:=False;
POPEDInfo^.EditorStartLine:=EditorLineNumber;
Exit;
END;
If copy(ss,1,7) = '$quotes' then
BEGIN
Delete(ss,1,7);
If md=5 then
BEGIN
UseThisLine:=False;
DoQuotes;
END;
END;
(* If not CheckForKeyWord(ss,'$quotes',5,md) then
BEGIN
UseThisLine:=False;
DoQuotes;
END;
*)
UseThis := CheckForKeyWord(ss,'$new',0,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$changed',1,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$comment',2,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$forward',3,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$moved',4,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$quoted',5,md);
If UseThis then UseThis := CheckForKeyWord(ss,'$reply',6,md);
UseThisLine := UseThis;
END ELSE
UseThisLine:=True;
END;
BEGIN
ProcessInfoRec;
New(t,INIT(Startpath+PopTemplateFileName,SOpenRead+ShareDenyW,2048));
New(tt,INIT(Startpath+TmpName3,SCreate,2048));
EditorLineNumber:=0;
POPEDInfo^.EditorStartLine:=1;
if t=NIL then exit;
if tt=nil then exit;
s:='';
While (not t^.eof) and (s<>'/POPED') do
t^.ReadLn(s);
If t^.eof then exit; {----------------------------------}
t^.ReadLn(s);
While (not t^.eof) and (s<> '/') do
BEGIN
If UseThisLine(s,MsgMode) then {UseThisLine also cuts prefixkeyword}
BEGIN
Case MsgMode of
0,1,2,3,4,5,6 : BEGIN
Replace(s,'$address',PopedInfo^.Address,99);
Replace(s,'$sysopname',PopedInfo^.SysOpName,99);
Replace(s,'$sysopfirstname',PopedInfo^.SysopFirstName,99);
Replace(s,'$sysoplastname',PopedInfo^.SysopLastName,99);
Replace(s,'$tosysopname',PopedInfo^.ToSysopName,99);
Replace(s,'$tosysopfirstname',PopedInfo^.ToSysopFirstName,99);
Replace(s,'$tosysoplastname',PopedInfo^.ToSysopLastName,99);
END;
END;
tt^.WriteLn(s);
Inc(EditorLineNumber);
END;
t^.ReadLn(s);
END;
tt^.WriteLn('--- PoPEd '+ver);
tt^.WriteLn(' * Origin: '+PopedArea^.Origin + ' ('+ PopEdInfo^.address + ')' );
Dispose(tt,Done);
Dispose(t,Done);
{ Assign(f,Startpath+TmpName3);
Rename(f,Startpath+TmpName); }
END;
(*
0 1 2 3 4 5 6
$new $changed $comment $forward $moved $quoted $reply
------------------------------------------------------------------------------
$address √ x x x x x x x
$curdate x x x x x x x
$curtime x x x x x x x
$description x x x x x x x
$echotag x x x x x x x
$message x x x x x x
$originaladdress x x x x
$originaldate x x x x
$originalsubject x x x x
$originalsysopfirstname x x x x
$originalsysoplastname x x x x
$originalsysopname x x x x
$originaltime x x x x
$originaltoaddress x x x x
$originaltosysopfirstname x x x x
$originaltosysoplastname x x x x
$originaltosysopname x x x x
$quotes x x
$sysopfirstname x x x x x x x
$sysoplastname x x x x x x x
$sysopname √ x x x x x x x
$toaddress x x x x x x
$tosysopfirstname x x x x x x
$tosysoplastname x x x x x x
$tosysopname x x x x x x
$fromaddress
$fromsysopfirstname
$fromsysoplastname
$fromsysopname
$new 0
$changed 1
$comment 2
$forward 3
$moved 4
$quoted 5
$reply 6
$position
*)
Procedure SaveMessage;
Var
t : Text;
TmpStr : String;
TmpAdr : TFidoAddress;
BEGIN
Assign(t,TmpName3);
Reset(t);
Msg^.StartNewMsg;
Msg^.SetFrom(PopedInfo^.SysopName);
Msg^.SetTo(PopedInfo^.ToSysopName);
Msg^.SetSubj(PopedInfo^.Subject);
Msg^.SetDate(DateStr(GetDosDate));
Msg^.SetTime(TimeStr(GetDosDate));
Msg^.SetLocal(True);
ParseAddr(PopEdInfo^.Address,TmpAdr,TmpAdr);
Msg^.SetOrig(TmpAdr);
ParseAddr(PopEdInfo^.ToAddress,TmpAdr,TmpAdr);
Msg^.SetDest(TmpAdr);
ReadLn(t,TmpStr);
Msg^.DoStringLn(TmpStr);
While (Not eof(t)) do
BEGIN
ReadLn(t,TmpStr);
Msg^.DoStringLn(TmpStr);
END;
Close(t);
Msg^.WriteMsg;
END;
Procedure EditHeader;
VAR
ESR : PpopEntryScreen;
Up : Pointer;
Offset : Byte;
BEGIN
NEW(ESR);
GetEsr(EsrPopedHeader,2,ESR^);
ESR^.UpdateScreenSize;
Offset:=(ScreenWidth-80) DIV 2;
ESR^.AdjustWindow(2+Offset,2,79+Offset,5);
ESR^.SetWrapMode(ExitAtBot);
up:=ESR^.GetUserRecord;
FillChar(up^,Sizeof(tPopedHeader),0);
TpopedHeader(up^).FromName:=cfg.sysop;
TpopedHeader(up^).ToName:=PopEdInfo^.OriginalSysopName;
TpopedHeader(up^).Subj:=PopEdInfo^.OriginalSubject;
TpopedHeader(up^).ToAddr:=PopEdInfo^.OriginalAddress;
If PopedArea^.UsedAKA = 0 then
TpopedHeader(up^).FromAddr:=Address2Str(Cfg.addresses[cfg.MainAdrNum])
ELSE
TpopedHeader(up^).FromAddr:=Address2Str(Cfg.addresses[POPEDArea^.UsedAKA]);
Esr^.Process;
PopedInfo^.SysopName := TpopedHeader(up^).FromName;
PopedInfo^.Address := TpopedHeader(up^).FromAddr;
PopedInfo^.ToSysopName := TpopedHeader(up^).ToName;
PopedInfo^.ToAddress := TpopedHeader(up^).ToAddr;
PopedInfo^.Subject := TpopedHeader(up^).Subj;
Dispose(Esr,Done);
END;
Procedure EditMessage;
Var
TeSize : LongInt;
BEGIN
TeSize:=16000;
New(EditorWin, InitCustom(1,7,ScreenWidth,ScreenHeight,Cfg.Color[3],DefWindowOptions,TeSize));
If EditorWin=Nil then
BEGIN
AskError(8,'Could not open Editor:'+Long2Str(Maxavail),4);
Exit;
end;
EditorWin^.SetMaxLength(80);
EditorCommands.AddCommand(ccQuit, 1, Word(283), 0); {Esc}
EditorCommands.AddCommand(ccUser11, 1, Word(11520), 0); {Alt-X}
EditorWin^.ReadFile(TmpName3, TeSize);
EditorWin^.Draw;
EditorWin^.GotoLineCol(POPEDInfo^.EditorStartLine,1);
EditorWin^.ProcessSelf;
IF EditorWin^.GetLastCommand = ccQuit THEN EditorWin^.SaveFile;
EditorWin^.Erase;
Dispose(EditorWin,Done);
END;
Function MsgFlags2Str:String;
Var
TmpStr : String;
BEGIN
TmpStr:='';
If Msg^.IsLocal Then TmpStr:=TmpStr+'Loc ';
If Msg^.IsCrash Then TmpStr:=TmpStr+'Cra ';
If Msg^.IsKillSent Then TmpStr:=TmpStr+'K/S ';
If Msg^.IsSent Then TmpStr:=TmpStr+'Snt ';
If Msg^.IsFAttach Then TmpStr:=TmpStr+'Att ';
If Msg^.IsReqRct Then TmpStr:=TmpStr+'RRq ';
If Msg^.IsReqAud Then TmpStr:=TmpStr+'ARq ';
If Msg^.IsRetRct Then TmpStr:=TmpStr+'RRc ';
If Msg^.IsFileReq Then TmpStr:=TmpStr+'Frq ';
If Msg^.IsRcvd Then TmpStr:=TmpStr+'Rcv ';
If Msg^.IsPriv Then TmpStr:=TmpStr+'Pvt ';
If Msg^.IsDeleted Then TmpStr:=TmpStr+'Del ';
{ If Msg^.IsEchoed Then TmpStr:=TmpStr+'Ech '; }
MsgFlags2Str := TmpStr;
END;
PROCEDURE ShowHeader;
Var
TmpStr : String;
TmpAdr : TFidoAddress;
BEGIN
TmpStr :='#'+Long2Str(Msg^.GetMsgNum)+' ['+Long2Str(Msg^.GetMsgDisplayNum);
TMpStr :=TmpStr+' of '+Long2Str(Msg^.NumberOfMsgs)+'] ';
If Msg^.GetRefer <> 0 then
TmpStr:=TmpStr+'-'+Long2Str(Msg^.GetRefer)+' ';
If Msg^.GetSeeAlso <> 0 then
TmpStr:=TmpStr+'+'+Long2Str(Msg^.GetSeeAlso);
TmpStr:=Pad(TmpStr,35);
HeaderWin^.wFasttext('Msg : '+TmpStr,1,2);
HeaderWin^.wFasttext(Pad(MsgFlags2Str,35),1,45);
HeaderWin^.wFasttext('From : '+pad(Msg^.GetFrom,35),2,2);
HeaderWin^.wFasttext('To : '+pad(Msg^.GetTo,35),3,2);
HeaderWin^.wFasttext('Subj.: '+pad(Msg^.GetSubj,72),4,2);
Msg^.GetOrig(TmpAdr);
HeaderWin^.wFasttext(Pad(Address2Str(TmpAdr),20),2,45);
Msg^.GetDest(TmpAdr);
HeaderWin^.wFasttext(Pad(Address2Str(TmpAdr),20),3,45);
HeaderWin^.wFasttext(Msg^.GetDate+' '+Msg^.GetTime,2,65);
{ HeaderWin^.wFasttext(Long2Str(StackPos)+' ',2,65); }
END;
Function Browse(s:String): LongInt;
BEGIN
BrowseWin^.OpenFile(s);
Status := BrowseWin^.GetLastError;
if Status <> 0 then begin
{ ErrorProc(0,InitStatus,'Failed to load File'); }
Exit;
end;
{use built-in status routine}
{ BrowseWin^.SetErrorProc(ErrorProc); }
Finished := False;
repeat
BrowseWin^.Process;
case BrowseWin^.GetLastCommand of
ccQuit, ccError,
ccUser1, ccUser2,
ccUser3, ccUser4,
ccUser5, ccUser6,
ccUser7, ccUser8
: Finished := True;
{...user exit commands...}
end;
until Finished;
BrowseWin^.CloseFile;
Browse:=BrowseWin^.GetLastCommand;
END;
Procedure Dump2File;
Var
t : PBufTextFile;
TmpStr : String;
BEGIN
New(t, Init(TmpName, SCreate, 2048));
Msg^.MsgTxtStartUp;
t^.WriteLn(Msg^.GetString(StLen));
While (Not Msg^.EOM) do
BEGIN
t^.WriteLn(Msg^.GetString(StLen));
END;
Dispose(t,Done);
END;
Procedure BrowseDispose;
BEGIN
BrowseWin^.Erase;
Dispose(BrowseWin,Done);
BrowseWin:=NIL;
END;
Function BrowseInit: Boolean;
BEGIN
BrowseInit:=True;
New(BrowseWin, InitCustom(1,7,ScreenWidth,ScreenHeight,Cfg.Color[3],DefWindowOptions,16384));
If BrowseWin=Nil then
BEGIN
AskError(8,'Could not open browser:'+Long2Str(Maxavail),4);
BrowseInit:=False;
end;
BrowseCommands.AddCommand(ccUser1, 1, Word(256*75), 0); { Left }
BrowseCommands.AddCommand(ccUser2, 1, Word(256*77), 0); { Right }
BrowseCommands.AddCommand(ccUser3, 1, Word(256*83), 0); { Delete }
BrowseCommands.AddCommand(ccUser4, 1, Word(11875 ), 0); { c }
BrowseCommands.AddCommand(ccUser5, 1, Word(30464 ), 0); { ctrl-Home }
BrowseCommands.AddCommand(ccUser6, 1, Word(4709 ), 0); { e }
BrowseCommands.AddCommand(ccUser7, 1, Word(4978 ), 0); { r }
END;
Function OpenMsgArea(Directory:String;MsgBaseType:Byte):Boolean;
VAR
MsgID : String;
BEGIN
OpenMsgArea:=True;
Case MSGBaseType of
0 : MsgID:='H'+LeftPadCh(JustName(Directory),'0',3)+AddBackSlash(JustPathName(Directory));
1 : MsgID:='F'+Directory;
2 : MsgID:='S'+Directory;
3 : MsgID:='E'+Directory;
4 : MsgID:='J'+Directory;
END;
If not OpenOrCreateMsgArea(Msg, MsgID) then
BEGIN
AskError(8,'Could not open message area',4);
OpenMsgArea:=False;
Exit;
END;
END;
Function OpenArea(Directory:String;MsgBaseType:Byte):Boolean;
BEGIN
If not OpenMsgArea(Directory,MsgBaseType) then exit else OpenArea:=True;
MyWin(HeaderWin,1,1,80,6,3,'PopEd v'+ver,False);
{ Msg^.SetMailType(mmtEchoMail); }
MsgNumber:=Msg^.GetLastRead(0);
OpenArea:=BrowseInit;
END;
PROCEDURE CloseArea;
BEGIN
BrowseDispose;
Msg^.SetLastRead(0,MsgNumber);
KillWindow(HeaderWin);
CloseMsgArea(Msg);
END;
Procedure NotFound;
VAR
t : Text;
BEGIN
If Msg^.GetMsgDisplayNum < Msg^.GetHighMsgNum then
Msg^.SeekNext
ELSE
Msg^.SeekPrior;
If not Msg^.SeekFound then
BEGIN
Assign(t,TmpName);
ReWrite(t);
WriteLn(T,'');
Close(t);
MsgNumber:=0;
Exit;
END;
END;
Procedure LoadMessage; {Use First Time}
VAR
TmpAdr : TFidoAddress;
BEGIN
Msg^.SeekFirst(MsgNumber);
If not Msg^.SeekFound then
NotFound;
If MsgNumber <> 0 then
BEGIN
Msg^.MsgStartUp;
Dump2File;
PopEdInfo^.OriginalSysopName:=Msg^.GetFrom;
PopEdInfo^.OriginalToSysopName:=Msg^.GetTo;
Msg^.GetOrig(TmpAdr);
PopEdInfo^.OriginalAddress:=(Address2Str(TmpAdr));
Msg^.GetDest(TmpAdr);
PopEdInfo^.OriginalToAddress:=(Address2Str(TmpAdr));
PopEdInfo^.OriginalSubject:=Msg^.GetSubj;
END;
END;
Procedure EnterNewMsg;
VAR
GemMsgNumber : LongInt;
BEGIN
GemMsgNumber := MsgNumber;
EditHeader;
ProcessTemplate(0);
BrowseDispose;
EditMessage;
SaveMessage;
BrowseInit;
MsgNumber := GemMsgNumber;
LoadMessage;
END;
Procedure EnterReplyMsg;
VAR
GemMsgNumber : LongInt;
BEGIN
GemMsgNumber := MsgNumber;
EditHeader;
ProcessTemplate(5);
BrowseDispose;
EditMessage;
SaveMessage;
BrowseInit;
MsgNumber := GemMsgNumber;
LoadMessage;
END;
Procedure NextMessage;
BEGIN
If MsgNumber < Msg^.GetHighMsgNum then
BEGIN
Msg^.SeekNext;
If not Msg^.SeekFound then
NotFound;
If MsgNumber <> 0 then
BEGIN
Msg^.MsgStartUp;
MsgNumber:=Msg^.GetMsgNum;
Dump2File;
END;
END;
END;
Procedure PrevMessage;
BEGIN
Msg^.SeekPrior;
If not Msg^.SeekFound then
NotFound;
If MsgNumber <> 0 then
BEGIN
Msg^.MsgStartUp;
MsgNumber:=Msg^.GetMsgNum;
Dump2File;
END;
END;
Procedure DeleteMessage;
BEGIN
Msg^.DeleteMsg;
PrevMessage;
NextMessage;
END;
PROCEDURE BrowseText;
Var
Finished2 : Boolean;
BEGIN
Finished2 := False;
LoadMessage;
While not Finished2 do
BEGIN
ShowHeader;
Case Browse(TmpName) of
ccUser1 : If MsgNumber<>0 then PrevMessage;
ccUser2 : If MsgNumber<>0 then NextMessage;
ccUser3 : If MsgNumber<>0 then DeleteMessage;
{ ccUser4 : If MsgNumber<>0 then EditMessage; }
ccUser4 : If MsgNumber<>0 then EditHeader;
ccUser6 : If MsgNumber<>0 then EnterNewMsg;
ccUser7 : If MsgNumber<>0 then EnterReplyMsg;
ccUser5 : If MsgNumber<>0 then
BEGIN
MsgNumber:=1;
LoadMessage;
END;
ELSE
Finished2 := True;
END;
END;
END;
{----------------------------------------------------------------------------}
FUNCTION _GetPoPEdStr(VAR Buffer): String; far;
VAR
s : STRING;
BEGIN
WITH TPOPEDArea(Buffer) DO
BEGIN
s:=Pad(Description,40)+' '+Pad(EchoNames[1],20)+' '+
LeftPad(Long2Str(NumMsg),7)+LeftPad(Long2Str(NumMsg-LastRead),7);
END;
_GetPoPEdStr:=s;
END;
PROCEDURE _EditPoPEd(VAR Buffer; VAR Changed: Boolean; RecNum, MaxRec: LongInt); far;
BEGIN
If OpenArea(TPOPEDarea(Buffer).Directory,TPOPEDArea(Buffer).AreaType) then
BEGIN
If (MsgNumber>Msg^.GetHighMsgNum) or (MsgNumber<1) then MsgNumber:=1;
Msg^.SeekFirst(MsgNumber);
If Msg^.SeekFound then
BEGIN
Msg^.SeekNext;
If MSG^.SeekFound then
MsgNumber:=Msg^.GetMsgNum;
END;
BrowseText;
TPOPEDarea(Buffer).NumMsg:=MSG^.NumberOfMsgs;
TPOPEDarea(Buffer).LastRead:=MSG^.GetMsgDisplayNum;
CloseArea;
END;
Changed := True;
{ Esr.Select;
Esr.SetNextField(0);
Esr.Draw;
}
END;
PROCEDURE _InitPoPEd(VAR Buffer); far;
BEGIN
{ FillChar(Buffer,SizeOf(TMsgArea),0); }
END;
FUNCTION _IsGreaterPoPEd(VAR B1,B2): Boolean; far;
BEGIN
_IsGreaterPoPEd:=TPOPEDArea(B1).EchoNames[1]>TPOPEDArea(B2).EchoNames[1];
END;
PROCEDURE PoPEdPostEdit(Esr: EntryScreenPtr); far;
BEGIN
{ IF (ESR^.CurrentFieldModified) THEN Save:=True;}
END;
PROCEDURE BrowseAreas;
VAR
p : POINTER;
ExitCode : WORD;
Procedure ScanForNewMsg;
Var
POPArea : TMSGArea;
BEGIN
While Not EOF(f) do
BEGIN
NetRead(f,PopArea,false,false);
PopEdArea^.Directory := PopArea.Directory;
PopEdArea^.EchoNames[1] := PopArea.EchoNames[1];
PopEdArea^.EchoNames[2] := PopArea.EchoNames[2];
PopEdArea^.EchoNames[3] := PopArea.EchoNames[3];
PopEdArea^.Origin := PopArea.Origin;
PopEdArea^.Pvt2EMail := PopArea.Pvt2EMail;
PopEdArea^.Description:= PopArea.Description;
PopEdArea^.AreaType := PopArea.AreaType;
PopEdArea^.UsedAka := PopArea.UsedAka;
OpenMsgArea(PopEdArea^.Directory,PopEdArea^.AreaType);
Msg^.SeekFirst(Msg^.GetLastRead(0));
If not Msg^.SeekFound then
NotFound;
PopEdArea^.NumMsg:=Msg^.NumberOfMsgs;
PopEdArea^.LastRead:=Msg^.GetMsgDisplayNum;
CloseMsgArea(MSG);
NetWrite(ff,POPEDArea^)
END;
END;
BEGIN
Deletefile(StartPath+TmpName2);
NetOpenFile(ff,StartPath+TmpName2,SizeOf(TPOPEDArea),True);
NetOpenFile(f,StartPath+PoPMsgAreaFileName,SizeOf(TMsgArea),True);
ScanForNewMsg;
NetCloseFile(f);
Allowed:=10;
BrowseRecords(ff,Popedarea^,ExitCode,'Message Areas',
Pad('Area',41)+Pad('Tag',21)+LeftPad('Msgs',7)+LeftPad('New',7),
_GetPoPEdStr,_EditPoPEd,_InitPoPEd,_IsGreaterPoPEd);
{ Esr.Done;}
NetCloseFile(ff);
END;
PROCEDURE PopEdMain;
BEGIN
{$IFNDEF PoPLite}
{ FreeUpMemory; }
New(PopEdArea);
New(PopEdInfo);
BrowseAreas;
Dispose(PopEdInfo);
Dispose(PopEdArea);
{ InitialiseNodelist(cfg.NodeList,cfg.nodelisttyp); }
{$ELSE}
AddLog('!','Not implemented in Portal of Power/Lite');
{$ENDIF}
END;
END.